package com.hulk.dryad.manage.config;


import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.hulk.dryad.manage.config.resolver.SqlFilterArgumentResolver;
import com.hulk.dryad.persistence.handler.CommonMetaObjectHandler;
import com.hulk.dryad.persistence.injector.datascope.DataScopeHandle;
import com.hulk.dryad.persistence.injector.datascope.DataScopeInnerInterceptor;
import com.hulk.dryad.persistence.injector.datascope.DataScopeSqlInjector;
import com.hulk.dryad.persistence.injector.datascope.DefaultDatascopeHandle;
import org.apache.ibatis.type.EnumTypeHandler;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.sql.DataSource;
import java.util.List;

/**
 * <p>
 *
 * @author kim
 * @date 2021/1/15
 */
@Configuration
@ConditionalOnClass(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class DryadMybatisPlusConfig implements WebMvcConfigurer {


	@Bean
	public MetaObjectHandler metaObjectHandler(){
		return new CommonMetaObjectHandler();
	}

	/**
	 * 增加请求参数解析器，对请求中的参数注入SQL 检查
	 * @param resolverList
	 */
	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolverList) {
		resolverList.add(new SqlFilterArgumentResolver());
	}

	/**
	 * 默认数据权限处理器
	 * @return DefaultDatascopeHandle
	 */
	@Bean
	@ConditionalOnMissingBean
	public DataScopeHandle dataScopeHandle() {
		return new DefaultDatascopeHandle();
	}


	/**
	 * mybatis plus 拦截器配置
	 * @return MybatisPlusInterceptor
	 */
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		// 数据权限
		DataScopeInnerInterceptor dataScopeInnerInterceptor = new DataScopeInnerInterceptor();
		dataScopeInnerInterceptor.setDataScopeHandle(dataScopeHandle());
		interceptor.addInnerInterceptor(dataScopeInnerInterceptor);
		// 分页支持
		interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
		// 乐观锁
		interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
		interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
		/*interceptor.addInnerInterceptor(new DynamicTableNameInnerInterceptor());*/
		return interceptor;
	}

	/**
	 * IEnum 枚举配置
	 */
	@Bean
	public ConfigurationCustomizer configurationCustomizer() {
		return new MybatisPlusCustomizers();
	}

	/**
	 * 自定义配置
	 */
	public static class MybatisPlusCustomizers implements ConfigurationCustomizer {
		@Override
		public void customize(MybatisConfiguration configuration) {
			configuration.setDefaultEnumTypeHandler(EnumTypeHandler.class);
			configuration.setUseDeprecatedExecutor(false);
		}
	}

	/**
	 * 扩展 mybatis-plus baseMapper 支持数据权限
	 * @return DataScopeSqlInjector
	 */
	@Bean
	@ConditionalOnBean(DataScopeHandle.class)
	public DataScopeSqlInjector dataScopeSqlInjector() {
		return new DataScopeSqlInjector();
	}


}
